﻿using ShaderEffectLibrary;
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace SharpSoft.WPF.Controls
{
    public class WaterwaveEffectControl : ContentControl
    {
        static WaterwaveEffectControl()
        {
            //DefaultStyleKeyProperty.OverrideMetadata(typeof(WaterwaveEffectControl), new FrameworkPropertyMetadata(typeof(WaterwaveEffectControl)));
        }

        public WaterwaveEffectControl()
        {
            this.resetTemplate();
        }
        /// <summary>
        /// 最多能产生的水波数量
        /// </summary>
        public int MaxCount
        {
            get { return (int)GetValue(MaxCountProperty); }
            set { SetValue(MaxCountProperty, value); }
        }

        public static readonly DependencyProperty MaxCountProperty =
            DependencyProperty.Register("MaxCount", typeof(int), typeof(WaterwaveEffectControl), new PropertyMetadata(6, new PropertyChangedCallback(maxCountChanged)));

        static void maxCountChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            if (obj is WaterwaveEffectControl wwec)
            {
                wwec.resetTemplate();
            }
        }

        private void resetTemplate()
        {
            var ct = new ControlTemplate(typeof(WaterwaveEffectControl));
            FrameworkElementFactory f = new FrameworkElementFactory(typeof(Grid), "Grid");
            FrameworkElementFactory p = f;
            for (int i = 0; i < this.MaxCount; i++)
            {
                FrameworkElementFactory b = new FrameworkElementFactory(typeof(Border), $"Border_{i}");
                p.AppendChild(b);
                p = b;
            }


            FrameworkElementFactory cp = new FrameworkElementFactory(typeof(ContentPresenter), $"ContentPresenter");
            p.AppendChild(cp);
            cp.SetBinding(ContentPresenter.ContentProperty, new Binding("Content") { RelativeSource = new RelativeSource(RelativeSourceMode.TemplatedParent), Mode = BindingMode.OneWay });
            ct.VisualTree = f;
            this.Template = ct;
        }

        private Border[] borders;

        private DependencyObject GetBorder(int index)
        {
            return this.GetTemplateChild($"Border_{index}");
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            List<Border> list = new List<Border>();
            for (int i = 0; i < this.MaxCount; i++)
            {
                list.Add((Border)GetBorder(i));
            }
            borders = list.ToArray();
        }
        /// <summary>
        /// 获取没有正在进行水波动画的border
        /// </summary>
        /// <returns></returns>
        private Border GetFreeBorder()
        {
            if (borders != null)
            {

                foreach (var item in borders)
                {
                    if (item.Effect == null)
                    {
                        return item;
                    }
                }
            }
            return null;
        }

        private void doAnimation(Point point, Border border)
        {
            if (border == null)
            {
                return;
            }
            RippleEffect rippleEffect = new RippleEffect() { Amplitude = 0, Frequency = 0, Phase = 0, Center = point };
            border.Effect = rippleEffect;

            var dur = TimeSpan.FromSeconds(1.2);
            Storyboard sb = new Storyboard() { FillBehavior = FillBehavior.Stop, };

            DoubleAnimationUsingKeyFrames fs = new DoubleAnimationUsingKeyFrames() { Duration = dur };//频率动画
            fs.KeyFrames.Add(new LinearDoubleKeyFrame(30, KeyTime.FromPercent(0)));
            //fs.KeyFrames.Add(new LinearDoubleKeyFrame(40, KeyTime.FromPercent(0.1)));
           // fs.KeyFrames.Add(new LinearDoubleKeyFrame(50, KeyTime.FromPercent(0.9)));
            fs.KeyFrames.Add(new LinearDoubleKeyFrame(0, KeyTime.FromPercent(1)));
            Storyboard.SetTargetProperty(fs, new PropertyPath("(0).(1)", Border.EffectProperty, RippleEffect.FrequencyProperty));
            Storyboard.SetTarget(fs, border);
            DoubleAnimationUsingKeyFrames fs1 = new DoubleAnimationUsingKeyFrames() { Duration = dur };//振幅动画
            fs1.KeyFrames.Add(new LinearDoubleKeyFrame(0, KeyTime.FromPercent(0)));
            fs1.KeyFrames.Add(new LinearDoubleKeyFrame(0.005, KeyTime.FromPercent(0.1)));
            fs1.KeyFrames.Add(new LinearDoubleKeyFrame(0.008, KeyTime.FromPercent(0.9)));
            fs1.KeyFrames.Add(new LinearDoubleKeyFrame(0, KeyTime.FromPercent(1)));
            Storyboard.SetTargetProperty(fs1, new PropertyPath("(0).(1)", Border.EffectProperty, RippleEffect.AmplitudeProperty));
            Storyboard.SetTarget(fs1, border);

            sb.Children.Add(fs);
            sb.Children.Add(fs1);
            sb.Completed += (s, e) =>
            {
                border.Effect = null;
            };
            sb.Begin();
        }

        public void Wave(Point point)
        {  
            var b = GetFreeBorder();
            if (b==null)
            {
                return;
            }
            var x = point.X / this.ActualWidth;
            var y = point.Y / this.ActualHeight;
            doAnimation(new Point(x, y), b);
        
        }
         
    }
}
